package Main;

import ICG.*;
import Include.*;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class main {
    public static void main(String[] args) {
        // 假设CmdParam和readCmdParam已经实现
        CmdParam cmdParam = readCmdParam(args);
        if (cmdParam == null || cmdParam.input.isEmpty()) {
            System.out.println("没有输入的文件或参数错误");
            return;
        }
        String filename = cmdParam.input.get(0);

        try {
            System.out.println("开始翻译文件：" + filename);

            // 读取文件并创建输入流
            CharStream input = CharStreams.fromFileName(filename);
            // 初始化词法分析器
            GoLexer lexer = new GoLexer(input);
            // 创建令牌流
            CommonTokenStream tokens = new CommonTokenStream(lexer);

            System.out.println("词法分析");


            // 初始化语法分析器
            GoParser parser = new GoParser(tokens);
            // 进行语法分析
            ParseTree tree = parser.sourceFile();
            System.out.println();

            System.out.println("语法分析");
            // 创建监听器，用于访问者模式
            TrCodeGen listener = new TrCodeGen();
            // 遍历语法树
            ParseTreeWalker.DEFAULT.walk(listener, tree);

            // 生成3地址代码文件
            String path_3code = cmdParam.output + "/" + cmdParam.output_3code;
            listener.Go23file_(path_3code);

            System.out.println("end");
            System.out.println();

            // 三地址到汇编代码部分
            // 属性TACBlocks来存储三地址代码
            System.out.println("开始翻译三地址代码到汇编代码");
            Map<String, List<TACLine>> tac_file = listener.TACBlocks;

            // check
            if (tac_file == null) {
                System.out.println("TACBlocks is null, cannot proceed with translation.");
                return; // 退出程序或采取其他适当的错误处理措施
            }

            // check
            if (listener.globalScope == null) {
                System.out.println("Error: globalScope is null. The translation process cannot proceed.");
                return;
            }

            // 从这里出现问题！！！！
            // 已解决！！！
            Translator translator = new Translator(tac_file, listener.globalScope);
            translator.Translate();
            String path_asm = cmdParam.output_asm;
            translator.OutputFile(path_asm);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static CmdParam readCmdParam(String[] argv) {
        CmdParam cmdParam = new CmdParam();
        cmdParam.log_file_name = argv[0];
        int i = 0;
        while (i < argv.length) {
            String argvI = argv[i];
            if (argvI.startsWith("-")) {
                switch (argvI) {
                    case "-h":
                    case "--help":
                        printHelp();
                        return null; // Exit after printing help
                    case "-o":
                    case "--output":
                        if (i + 1 >= argv.length) {
                            System.out.println("选项" + argvI + "没有给定值");
                            return null;
                        }
                        cmdParam.output = argv[++i];
                        break;
                    case "-3":
                    case "--3code":
                        cmdParam.output_3code = getArgument(argv, i);
                        break;
                    case "-a":
                    case "--asm":
                        cmdParam.output_asm = getArgument(argv, i);
                        break;
                    case "-b":
                    case "--bin":
                        cmdParam.output_bin = getArgument(argv, i);
                        break;
                    case "-l":
                    case "--log":
                        cmdParam.log_path = getArgument(argv, i);
                        break;
                    default:
                        System.out.println("未知参数" + argvI);
                        return null;
                }
            } else {
                cmdParam.input.add(argv[i]);
            }
            i++;
        }
        if (cmdParam.input.isEmpty()) {
            System.out.println("没有输入的 .go文件");
            return null;
        }
        // 创建输出目录
        new File(cmdParam.output).mkdirs();
        return cmdParam;
    }

    private static String getArgument(String[] argv, int i) {
        if (i + 1 >= argv.length) {
            System.out.println("选项需要值");
            return null;
        }
        return argv[++i];
    }

    private static void printHelp() {
        System.out.println("可选参数如下：");
        System.out.println("-h (--help): 帮助");
        System.out.println("-o (--output): [默认:.] 输出文件路径");
        System.out.println("-3 (--3code): [默认: 3code.txt] 输出 3code 文件名");
        System.out.println("-a (--asm): [默认: out.asm] 输出 asm 文件名");
        System.out.println("-b (--bin): [默认: out.bin] 输出 bin 文件名");
        System.out.println("-l (--log): [默认: log] 输出 log 目录");
    }

    // CmdParam 类需要根据Java的语法进行定义
    static class CmdParam {
        private List<String> input = new ArrayList<>();
        private String output = ".";
        private String output_3code = "3code.txt";
        private String output_asm = "out.asm";
        private String output_bin = "out.bin";
        private String log_path = "./log";
        private String log_file_name;

        private String inputBaseName; // 存储输入文件的基本名称
        // 其他字段和方法...
    }
}